package com.example.ymm.modules1.service.impl.hl.ex;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.ymm.base.BaseServiceImpl;
import com.example.ymm.dto.HengLiConstants;
import com.example.ymm.exception.YmException;
import com.example.ymm.model.TableList;
import com.example.ymm.model.YmPageDto;
import com.example.ymm.modules1.entity.hl.ex.*;
import com.example.ymm.modules1.mapper.ex.ExPublishPaperMapper;
import com.example.ymm.modules1.query.hl.ex.*;
import com.example.ymm.modules1.service.dto.heng.ex.*;
import com.example.ymm.modules1.service.hl.ex.*;
import com.example.ymm.modules1.socket.UserExWebSocket;
import com.example.ymm.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
//@DSTransactional
@Slf4j
@DS("slave2")
public class ExPublishPaperServiceImpl extends BaseServiceImpl<ExPublishPaperMapper, ExPublishPaper> implements ExPublishPaperService {

    @Autowired
    ExPaperService exPaperService;
    @Autowired
    ExQuestionService exQuestionService;
    @Autowired
    ExQuestionOptionService exQuestionOptionService;
    @Autowired
    ExPublishOptionService exPublishOptionService;
    @Autowired
    private ExPublishQuestionService exPublishQuestionService;
    @Autowired
    private ExPublishGroupService exPublishGroupService;

    @Autowired
    ExUserPaperService exUserPaperService;
    @Autowired
    ExTeamUserService exTeamUserService;
    @Autowired
    ExTeamService exTeamService;
    @Autowired
    ExUserAnserService exUserAnserService;
    @Autowired
    ExUserResidueService exUserResidueService;
    @Autowired
    private ExUserOptionService exUserOptionService;
    @Autowired
    ExUserGroupService exUserGroupService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ExCategoryService exCategoryServiceImpl;


    @Override
    public TableList<ExPublishPaper> list(ExPublishPaperQueryCriteria criteria, YmPageDto pageDto) {
        IPage<ExPublishPaper> page = new Page<ExPublishPaper>(pageDto.getPage(),pageDto.getPageSize());
        QueryWrapper predicate = QueryHelpPlus.getPredicate(ExPublishPaper.class, criteria);
        predicate.orderByDesc("create_time");
        baseMapper.selectPage(page, predicate);
        TableList<ExPublishPaper> tableList=new TableList(page);
        return tableList;
    }

    public List<ExPublishPaper> queryAll(ExPublishPaperQueryCriteria criteria) {
        QueryWrapper predicate = QueryHelpPlus.getPredicate(ExPublishPaper.class, criteria);
        predicate.orderByDesc("create_time");
        List<ExPublishPaper> result =baseMapper.selectList(predicate);
        return result;
    }

    @Override
    public void addPublishPaper(ExPublishPaper exPublishPaper) {
        ExPaper exPaper=new ExPaper();
        exPaper.setPaperId(exPublishPaper.getPaperId());
        ExPaper paper = exPaperService.paperDetail(exPaper);
        if(UtilValidate.isEmpty(paper)){
            throw new YmException("参数有误！");
        }
        exPublishPaper.setActive(1);
        exPublishPaper.setStatus(0);
        //如果是面试卷的话要开启状态
        if(paper.getRuleType()==0){
            exPublishPaper.setStatus(1);

        }
        exPublishPaper.setPaperName(paper.getName());
        saveOrUpdate(exPublishPaper);
        redisUtil.set("startPublishPaper:"+exPublishPaper.getPublishPaperId(),exPublishPaper.getPublishPaperId());
        /**
         * 组题-start
         */
        Integer model = paper.getModel();// 考试模式: 1单一模块 2整张试卷
//        List<ExPublishGroup> add_group=new ArrayList<>();
        if(model==1){
            List<ExPaperGroup> groups = paper.getGroups();
            for (int i = 0; i < groups.size(); i++) {
                ExPaperGroup exPaperGroup = groups.get(i);
                ExPublishGroup p_group=new ExPublishGroup();
                BeanUtils.copyProperties(exPaperGroup, p_group);

                p_group.setStatus(0);
                Integer limitTime=exPaperGroup.getLimitTime();
//                p_group.setStartTime(exPaperGroup.getStartTime());
                p_group.setPublishPaperId(exPublishPaper.getPublishPaperId());
                p_group.setModel(model);
                //计划开始实际
                String startTime = exPaperGroup.getStartTime();
                if(UtilValidate.isNotEmpty(startTime)){
                    String s_start = DateKit.dateFormat(new Date(), "yyyy-MM-dd " + startTime);
                    Date d_start = DateKit.dateFormat(s_start);

                    if(UtilValidate.isEmpty(limitTime)){
                        limitTime=paper.getLimitTime();
                    }
                    Date d_end = DateKit.dateAdd(6, d_start, limitTime);
                    p_group.setPlanStartTime(new Timestamp(d_start.getTime()));
                    p_group.setPlanEndTime(new Timestamp(d_end.getTime()));
                }

                exPublishGroupService.saveOrUpdate(p_group);
                //题目
                //组题
                chooseQuestion(exPaperGroup,paper,p_group,exPublishPaper);
            }
        }
        if(model==2){
            /**
             * 已废弃 2025-07-23
             */
            ExPaperGroup exPaperGroup1 = paper.getGroups().get(0);

            ExPublishGroup p_group=new ExPublishGroup();
            p_group.setCategoryName("整张试卷");
            p_group.setModel(model);
            p_group.setSort(1);
            p_group.setPublishPaperId(exPublishPaper.getPublishPaperId());
//            p_group.setPaperGroupId(exPaperGroup.getPaperGroupId());

            p_group.setStatus(0);
            Integer limitTime=exPaperGroup1.getLimitTime();
            p_group.setLimitTime(limitTime);
            if(paper.getRuleType()==0){
                p_group.setStatus(1);
            }
            p_group.setIsDerangeOption(exPaperGroup1.getIsDerangeOption());
            if(UtilValidate.isNotEmpty(paper.getLimitTime())){
                p_group.setStartTime(UtilValidate.isNotEmpty(exPublishPaper.getStartTime())?exPublishPaper.getStartTime():new Timestamp(System.currentTimeMillis()));
                //推算结束时间
                Date end_date = DateKit.dateAdd(6, new Date(p_group.getStartTime().getTime()), paper.getLimitTime());
                p_group.setEndTime(new Timestamp(end_date.getTime()));
            }
            exPublishGroupService.saveOrUpdate(p_group);
            //题目
            List<ExPaperGroup> groups = paper.getGroups();
            for (int i = 0; i < groups.size(); i++) {
                ExPaperGroup exPaperGroup = groups.get(i);
                //组题
                chooseQuestion(exPaperGroup,paper,p_group,exPublishPaper);

            }
        }

    }


    /**
     * 组题逻辑
     * @param exPaperGroup
     * @param paper
     */
    public void chooseQuestion(ExPaperGroup exPaperGroup,ExPaper paper,ExPublishGroup p_group,ExPublishPaper exPublishPaper){
        /**
         * 选题类型：0全部 1部分
         */
        List<String> questionIds=new ArrayList<>();
        List<ExQuestion> questionList=new ArrayList<>();
        List<ExPaperGroupQuestion> groupQuestionList=new ArrayList<>();
        Integer type = exPaperGroup.getType();
        if(type==0){
            ExQuestionQueryCriteria c1=new ExQuestionQueryCriteria();
            c1.setCategoryId(exPaperGroup.getCategoryId());
            List<ExQuestion> questions = exQuestionService.queryListSort(c1);
            questions.forEach(question->{
                questionIds.add(question.getQuestionId());
                questionList.add(question);
            });
        }
        else{
            List<ExPaperGroupQuestion> partQuestions = exPaperGroup.getPartQuestions();
            partQuestions.forEach(question->{
                questionIds.add(question.getQuestionId());
                groupQuestionList.add(question);
            });
        }
        /**
         * 是否打乱顺序
         * 是否打乱顺序:0 否 1是
         */
        Integer isDerange = paper.getIsDerange();
        if(isDerange==0){
            //不打乱顺序
            for (int j = 0; j < questionIds.size(); j++) {
                ExPublishQuestion exPublishQuestion = new ExPublishQuestion();
                exPublishQuestion.setQuestionId(questionIds.get(j));
                exPublishQuestion.setSort(j+1);
                exPublishQuestion.setPublishPaperId(exPublishPaper.getPublishPaperId());
                exPublishQuestion.setPublishGroupId(p_group.getPublishGroupId());
                exPublishQuestionService.saveOrUpdate(exPublishQuestion);
                ExQuestionOptionQueryCriteria c2=new ExQuestionOptionQueryCriteria();
                c2.setQuestionId(questionIds.get(j));
                List<ExQuestionOption> exQuestionOptions = exQuestionOptionService.queryAll(c2);
                List<ExPublishOption> options=new ArrayList<>();
                for (ExQuestionOption exQuestionOption : exQuestionOptions) {
                    ExPublishOption exPublishOption = new ExPublishOption();
                    exPublishOption.setOptionId(exQuestionOption.getOptionId());
                    exPublishOption.setSort(exQuestionOption.getSort());
                    exPublishOption.setPublishPaperId(exPublishPaper.getPublishPaperId());
                    exPublishOption.setPublishQuestionId(exPublishQuestion.getPublishQuestionId());
                    exPublishOption.setLetter(exQuestionOption.getLetter());
                    options.add(exPublishOption);
                }
                exPublishOptionService.saveOrUpdateBatch(options);
            }
        }
        else{
            //打乱顺序
            Collections.shuffle(questionIds);

            for (int j = 0; j < questionIds.size(); j++) {
                ExPublishQuestion exPublishQuestion = new ExPublishQuestion();
                exPublishQuestion.setQuestionId(questionIds.get(j));
                exPublishQuestion.setSort(j+1);
                exPublishQuestion.setPublishPaperId(exPublishPaper.getPublishPaperId());
                exPublishQuestion.setPublishGroupId(p_group.getPublishGroupId());
                exPublishQuestionService.saveOrUpdate(exPublishQuestion);
                ExQuestionOptionQueryCriteria c2=new ExQuestionOptionQueryCriteria();
                c2.setQuestionId(questionIds.get(j));
                List<ExQuestionOption> exQuestionOptions = exQuestionOptionService.queryAll(c2);

                /**
                 * 判断这个题目的选项字母能不能打乱顺序 -性格测试题不支持 把字母顺序打乱
                 */
                boolean can_shuffle=false;//是否可以打乱
                //是否打乱选项 ：0否 1是
                Integer isDerangeOption = exPaperGroup.getIsDerangeOption();
                if(UtilValidate.isNotEmpty(exQuestionOptions)&&UtilValidate.isNotEmpty(isDerangeOption)&&isDerangeOption==1){
                    can_shuffle=true;
                }
//                if(type==0){
//                    for (ExQuestion exQuestion : questionList) {
//                        if(exQuestion.getQuestionId().equals(questionIds.get(j))){
//                            if(exQuestion.getType().equals("性格与沟通")){
//                                can_shuffle=false;
//                            }
//                        }
//                    }
//                }else{
//                    for(ExPaperGroupQuestion groupQuestion: groupQuestionList){
//                        if(groupQuestion.getQuestionId().equals(questionIds.get(j))){
//                            if(groupQuestion.getType().equals("性格与沟通")){
//                                can_shuffle=false;
//                            }
//                        }
//                    }
//                }
                if(can_shuffle){
                    Collections.shuffle(exQuestionOptions);
                }

                List<ExPublishOption> options=new ArrayList<>();
                String letter_str="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                //先收集字母组
                Map<String,String> letter_map=new LinkedHashMap<>();
                for (int k = 0; k < exQuestionOptions.size(); k++) {
                    ExQuestionOption exQuestionOption = exQuestionOptions.get(k);
                    letter_map.put(exQuestionOption.getLetter(),exQuestionOption.getLetter());
                }
                String[] all = letter_str.split("");
                List<String> letter_arr = new ArrayList<>(letter_map.size());
                for (String s : all) {
                    if(letter_map.containsKey(s)){
                        letter_arr.add(letter_map.get(s));
                    }
                }
//                String[] letter_arr = letter_str.split("");
                for (int k = 0; k < exQuestionOptions.size(); k++) {
                    ExQuestionOption exQuestionOption=exQuestionOptions.get(k);
                    ExPublishOption exPublishOption = new ExPublishOption();
                    exPublishOption.setOptionId(exQuestionOption.getOptionId());
                    exPublishOption.setSort(k+1);
                    exPublishOption.setPublishPaperId(exPublishPaper.getPublishPaperId());
                    exPublishOption.setPublishQuestionId(exPublishQuestion.getPublishQuestionId());
                    if(can_shuffle){
                        exPublishOption.setLetter(letter_arr.get(k));
                    }else{
                        exPublishOption.setLetter(exQuestionOption.getLetter());
                    }

                    options.add(exPublishOption);
                }

                exPublishOptionService.saveOrUpdateBatch(options);
            }
        }
    }


    @Override
    public void removePublishPaper(ExPublishPaper exPublishPaper) {

        LambdaQueryWrapper<ExPublishOption> c1=new LambdaQueryWrapper<>();
        c1.eq(ExPublishOption::getPublishPaperId,exPublishPaper.getPublishPaperId());
        exPublishOptionService.remove(c1);

        LambdaQueryWrapper<ExPublishQuestion> c2=new LambdaQueryWrapper<>();
        c2.eq(ExPublishQuestion::getPublishPaperId,exPublishPaper.getPublishPaperId());
        exPublishQuestionService.remove(c2);

        LambdaQueryWrapper<ExPublishGroup> c3=new LambdaQueryWrapper<>();
        c3.eq(ExPublishGroup::getPublishPaperId,exPublishPaper.getPublishPaperId());
        exPublishGroupService.remove(c3);

        removeById(exPublishPaper.getPublishPaperId());
    }

    /**
     * 试卷详情
     * @param exPublishPaper
     */
    @Override
    public ExPublishPaper getPublishPaper(ExPublishPaper exPublishPaper) {
        ExPublishPaper publishPaper = getById(exPublishPaper.getPublishPaperId());
        if(UtilValidate.isEmpty(publishPaper)){
            throw new YmException("参数异常!");
        }
        ExPaper exPaper = exPaperService.getById(publishPaper.getPaperId());
        publishPaper.setExPaper(exPaper);
        ExPublishGroupQueryCriteria c1=new ExPublishGroupQueryCriteria();
        c1.setPublishPaperId(publishPaper.getPublishPaperId());
        List<ExPublishGroup> exPublishGroups = exPublishGroupService.queryAll(c1);

        ExPublishQuestionQueryCriteria c2=new ExPublishQuestionQueryCriteria();
        c2.setPublishPaperId(publishPaper.getPublishPaperId());
        List<ExPublishQuestion> exPublishQuestions = exPublishQuestionService.queryAll(c2);

        ExPublishOptionQueryCriteria c3=new ExPublishOptionQueryCriteria();
        c3.setPublishPaperId(publishPaper.getPublishPaperId());
        List<ExPublishOption> options = exPublishOptionService.queryAll(c3);
        for (ExPublishQuestion question: exPublishQuestions){
            List<ExPublishOption> os=new ArrayList<>();
            for (ExPublishOption exPublishOption : options) {
                if(question.getPublishQuestionId().equals(exPublishOption.getPublishQuestionId())){
                    os.add(exPublishOption);
                }
            }
            question.setOptions(os);
        }
        publishPaper.setQuestionAllNum(exPublishQuestions.size());
        for (ExPublishGroup group: exPublishGroups){
            List<ExPublishQuestion> qs=new ArrayList<>();
            for (ExPublishQuestion question: exPublishQuestions){
                if(group.getPublishGroupId().equals(question.getPublishGroupId())){
                    qs.add(question);
                }
            }
            group.setQuestions(qs);
        }
        publishPaper.setGroups(exPublishGroups);
        return publishPaper;
    }


    @Override
    public ExPublishPaper getSamplePaper(String publishPaperId) {
        ExPublishPaper publishPaper = getById(publishPaperId);
        if(UtilValidate.isEmpty(publishPaper)){
            return null;
        }
        ExPublishQuestionQueryCriteria c2=new ExPublishQuestionQueryCriteria();
        c2.setPublishPaperId(publishPaper.getPublishPaperId());
        List<ExPublishQuestion> exPublishQuestions = exPublishQuestionService.queryAll(c2);
        publishPaper.setQuestionAllNum(exPublishQuestions.size());
        return publishPaper;
    }


    @Override
    public synchronized ExUserPaper userJoinPaper(String userName, String publishPaperId) {
        ExUserPaperQueryCriteria criteria=new ExUserPaperQueryCriteria();
        criteria.setPublishPaperId(publishPaperId);
        criteria.setUserName(userName);
        String userId = getUserId();
        List<ExUserPaper> exUserPapers = exUserPaperService.queryAll(criteria);
        ExTeamUser teamUser = exTeamUserService.findByUserName(userName);
        ExUserPaper exUserPaper=new ExUserPaper();
        if(UtilValidate.isEmpty(exUserPapers)){
            exUserPaper.setPublishPaperId(publishPaperId);
            exUserPaper.setUserName(userName);
            if(UtilValidate.isNotEmpty(teamUser)){
                exUserPaper.setUserId(teamUser.getUserId());
            }else{
                exUserPaper.setUserId(userId);
            }
            exUserPaperService.save(exUserPaper);

            ExPaper paper = exPaperService.getByPublishPaperId(publishPaperId);
            if(paper.getRuleType()==0){
                //是面试试卷
                //生成个人模块开始和结束
                ExUserGroupQueryCriteria c1=new ExUserGroupQueryCriteria();
                c1.setPublishPaperId(publishPaperId);
                c1.setUserName(userName);
                List<ExUserGroup> exUserGroups = exUserGroupService.queryAll(c1);
                if(UtilValidate.isEmpty(exUserGroups)){
                    ExPublishGroupQueryCriteria c2=new ExPublishGroupQueryCriteria();
                    c2.setPublishPaperId(publishPaperId);
                    List<ExPublishGroup> exPublishGroups = exPublishGroupService.queryAll(c2);
                    List<ExUserGroup> addUserGroup=new ArrayList<>();
                    if(UtilValidate.isNotEmpty(exPublishGroups)){
                        for(ExPublishGroup group: exPublishGroups){
                            ExUserGroup userGroup=new ExUserGroup();
                            userGroup.setPublishGroupId(group.getPublishGroupId());
                            userGroup.setUserName(userName);
                            userGroup.setUserId(userId);
                            userGroup.setPublishPaperId(publishPaperId);
                            userGroup.setSort(group.getSort());
                            userGroup.setStatus(0);
                            userGroup.setGroupName(group.getCategoryName());
                            if(group.getSort()==1){
                                userGroup.setStatus(1);
                                Integer limitTime = group.getLimitTime();
                                if(UtilValidate.isNotEmpty(limitTime)){
                                    Date now=new Date();
                                    Date end_date = DateKit.dateAdd(6, now, limitTime);
                                    userGroup.setStartTime(new Timestamp(now.getTime()));
                                    userGroup.setEndTime(new Timestamp(end_date.getTime()));
                                }
                            }
                            userGroup.setUserPaperId(exUserPaper.getUserPaperId());
                            addUserGroup.add(userGroup);
                        }
                        if(UtilValidate.isNotEmpty(addUserGroup)){
                            exUserGroupService.saveOrUpdateBatch(addUserGroup);
                            //加入开始的定时标志 redis
                            if(paper.getIsCoerce()==1){
                                boolean b= redisUtil.setIfAbsent(RedisKeyManager.user_paper_key + exUserPaper.getUserPaperId(), exUserPaper.getUserPaperId(), 2, TimeUnit.HOURS);
                                log.info("--用户面试加入定时器:"+b+":userPaperId:"+exUserPaper.getUserPaperId());
                            }

                        }

                    }
                }
            }

        }else{
            exUserPaper=exUserPapers.get(0);
            ExPaper paper = exPaperService.getByPublishPaperId(publishPaperId);

            //查看是否有待重开记录
            ExUserResidueQueryCriteria c1=new ExUserResidueQueryCriteria();
            c1.setUserPaperId(exUserPaper.getUserPaperId());
            c1.setIsStart(0);
            List<ExUserResidue> exUserResidues = exUserResidueService.queryAll(c1);
            if(UtilValidate.isNotEmpty(exUserResidues)){
                ExUserResidue exUserResidue = exUserResidues.get(0);
                ExUserGroupQueryCriteria c5=new ExUserGroupQueryCriteria();
                c5.setPublishPaperId(publishPaperId);
                c5.setUserPaperId(exUserPaper.getUserPaperId());
                List<ExUserGroup> exUserGroups = exUserGroupService.queryAll(c5);
                ExUserGroup userGroup=null;

                if(UtilValidate.isNotEmpty(exUserGroups)){
                    for(ExUserGroup group: exUserGroups){
                        if(group.getPublishGroupId().equals(exUserResidue.getPublishGroupId())){
                            userGroup=group;
                        }
                    }
                }
                if(UtilValidate.isNotEmpty(userGroup)){
                    ExPublishGroup publishGroup = exPublishGroupService.getById(userGroup.getPublishGroupId());

                    //重新计算开始时间和结束时间
                    userGroup.setStatus(1);
                    Integer limitTime = publishGroup.getLimitTime();
                    Date now=new Date();
                    Date end_date = DateKit.dateAdd(6, now, limitTime);
                    userGroup.setStartTime(new Timestamp(now.getTime()));
                    userGroup.setEndTime(new Timestamp(end_date.getTime()));
                    exUserGroupService.saveOrUpdate(userGroup);

                    exUserResidue.setIsStart(1);
                    exUserResidueService.saveOrUpdate(exUserResidue);
                    //加入开始的定时标志 redis
                    if(paper.getIsCoerce()==1){
                        boolean b= redisUtil.setIfAbsent(RedisKeyManager.user_paper_key + exUserPaper.getUserPaperId(), exUserPaper.getUserPaperId(), 2, TimeUnit.HOURS);
                        log.info("--重考加入定时器:"+b+":userPaperId:"+exUserPaper.getUserPaperId());
                    }
                }
            }
        }
        return exUserPaper;

    }

    @Override
    public ExPublishPaper getUserPaper(String userName,String publishPaperId) {
        ExPublishPaper g2=new ExPublishPaper();
        g2.setPublishPaperId(publishPaperId);
        ExPublishPaper publishPaper = getPublishPaper(g2);
        ExPublishQuestionQueryCriteria c2=new ExPublishQuestionQueryCriteria();
        c2.setPublishPaperId(publishPaper.getPublishPaperId());
        List<ExPublishQuestion> exPublishQuestions = exPublishQuestionService.queryAll(c2);
        publishPaper.setQuestionAllNum(exPublishQuestions.size());

        List<ExPublishGroup> groups = publishPaper.getGroups();

        ExPaper exPaper = publishPaper.getExPaper();
        ExPublishGroup start_group=null;
        publishPaper.setRuleType(exPaper.getRuleType());
        //计分规则：1 区分团队 0 普通计分（面试）
        if(exPaper.getRuleType()==1){
            //团队考试规则

            Integer groupIndex=publishPaper.getGroupIndex();
            start_group=groups.get(groupIndex);
            //打乱顺序
            if(UtilValidate.isNotEmpty(start_group)){

                List<ExPublishQuestion> questions = start_group.getQuestions();
                for(ExPublishQuestion question: questions){
                    //区分团队
                    if(exPaper.getRuleType()==1){
                        //字母集合
                        List<String> arr=new ArrayList<>();
                        List<ExPublishOption> options = question.getOptions();
                        for(ExPublishOption option: options){
                            arr.add(option.getLetter());
                        }
                        if(exPaper.getIsDerange()==1&&UtilValidate.isNotEmpty(start_group.getIsDerangeOption())&&start_group.getIsDerangeOption()==1){
                            //打乱选项
                            Collections.shuffle(options);
                        }

                        for(int i=0; i<options.size(); i++){
                            options.get(i).setLetter(arr.get(i));
                        }
                    }

                }

                //区分团队
                if(exPaper.getRuleType()==1){
                    //选打乱题目
                    Collections.shuffle(questions);

                    //重新排序
                    for (int i = 0; i < questions.size(); i++) {
                        ExPublishQuestion publishQuestion = questions.get(i);
                        publishQuestion.setSort(i+1);
                    }
                    start_group.setQuestions(questions);
                }

            }

            publishPaper.setStartGroup(start_group);
            ExPublishGroup nextGroup=null;//下一组
            if(groupIndex<groups.size()-1){
                ExPublishGroup group = groups.get(groupIndex + 1);
                if(group.getStatus().equals(0)){
                    // 如果下一组考过了 就不会到下一组里面
                    nextGroup= group;
                }
            }
            publishPaper.setNextGroup(nextGroup);
            //publishPaper.setGroupIndex(groupIndex);
            if(UtilValidate.isNotEmpty(start_group)){
                if(start_group.getStatus()==1){
                    Date now=new Date();
                    //计算剩余时间
                    //区分团队
                    if(exPaper.getRuleType()==1){
                        //                System.out.println("---now:"+DateKit.dateFormat(now,"yyyy-MM-dd HH:mm:ss")+";end-time:"+start_group.getEndTime());
                        if(UtilValidate.isNotEmpty(start_group.getEndTime())){
                            long d=start_group.getEndTime().getTime()- now.getTime();
                            if(d>0){
                                BigDecimal limit=  new BigDecimal(d).divide(new BigDecimal(1000)).setScale(0,BigDecimal.ROUND_HALF_UP);
                                start_group.setResidueTime(limit.intValue()+2);
                            }
                        }
                    }

                }
                ExUserAnserQueryCriteria criteria=new ExUserAnserQueryCriteria();
                criteria.setUserName(userName);
                criteria.setPublishPaperId(publishPaperId);
                criteria.setPublishGroupId(start_group.getPublishGroupId());
                UserAnserDto userScore = exUserAnserService.getUserScore(criteria);
                if(UtilValidate.isNotEmpty(userScore.getQuestionNum())&&userScore.getQuestionNum()>0){
                    GroupOneResultDto oneResultDto=new GroupOneResultDto();
                    oneResultDto.setGroupName(start_group.getCategoryName());
                    oneResultDto.setRuleType(exPaper.getRuleType());
                    oneResultDto.setQuestionType("选择题");

                    if(userScore.getQuestionNum()!=null&&userScore.getQuestionNum()>0){
                        oneResultDto.setSubmit(true);
                        oneResultDto.setResult1(userScore);
                    }

                    publishPaper.setUserScore(oneResultDto);
                }

            }

        }
        else{
            //人力面试

            //获取正在进行的模块
            ExUserGroupQueryCriteria c22=new ExUserGroupQueryCriteria();
            c22.setPublishPaperId(publishPaperId);
            c22.setUserName(userName);
            List<ExUserGroup> exUserGroups = exUserGroupService.queryAll(c22);
            Integer index=null;
            Integer over_num=0;//已完成答题的模块数量
            for (int i = 0; i < exUserGroups.size(); i++) {
                ExUserGroup exUserGroup = exUserGroups.get(i);
                if(exUserGroup.getStatus()==1){
                    index=i;
                }
                if(exUserGroup.getStatus()==2){
                    over_num++;
                }
            }
            for(ExUserGroup exUserGroup: exUserGroups){
                for (ExPublishGroup publishGroup:groups){
                    if(exUserGroup.getPublishGroupId().equals(publishGroup.getPublishGroupId())){
                        publishGroup.setStatus(exUserGroup.getStatus());
                        publishGroup.setStartTime(exUserGroup.getStartTime());
                        publishGroup.setEndTime(exUserGroup.getEndTime());
                        publishGroup.setCreateTime(exUserGroup.getCreateTime());
                    }
                }
            }
            //如果没有在 进行的模块就默认 开启第一个模块
            if(index==null&&over_num<exUserGroups.size()){
                index=0;

                ExUserGroup exUserGroup = exUserGroups.get(index);
                exUserGroup.setStatus(1);
                exUserGroupService.saveOrUpdate(exUserGroup);
            }else if(over_num==exUserGroups.size()){
                //最后一个模块结束了
                start_group=groups.get(exUserGroups.size()-1);
                List<ExPublishQuestion> questions = start_group.getQuestions();
                String type = questions.get(0).getType();
                String questionType="";
                if(UtilValidate.isNotEmpty(type)){
                    if(HengLiConstants.xing_ge_question.equals(type)){
                        questionType="性格测试题";
                    }else{
                        questionType="选择题";
                    }
                }
                GroupOneResultDto oneResultDto=new GroupOneResultDto();
                oneResultDto.setGroupName(start_group.getCategoryName());
                oneResultDto.setRuleType(exPaper.getRuleType());
                oneResultDto.setPaperOver(true);
                if("性格测试题".equals(questionType)){
                    oneResultDto.setQuestionType("性格测试题");
                    ExUserAnserQueryCriteria c13=new ExUserAnserQueryCriteria();
                    c13.setPublishPaperId(publishPaperId);
                    c13.setUserName(userName);
                    c13.setPublishGroupId(start_group.getPublishGroupId());
                    UserXingGeAnserDto xingGeAnserDto = exUserAnserService.xinGeCountLetterGroup(c13);
                    if(UtilValidate.isNotEmpty(xingGeAnserDto)){
                        oneResultDto.setSubmit(true);
                        oneResultDto.setResult2(xingGeAnserDto);
                    }
                    /**
                     * 判断是否需要打乱选项
                     */
                    if(exPaper.getIsDerange()==1){
                        //不打乱选项
                        //选打乱题目
                        Collections.shuffle(questions);

                        //重新排序
                        for (int i = 0; i < questions.size(); i++) {
                            ExPublishQuestion publishQuestion = questions.get(i);
                            publishQuestion.setSort(i+1);
                        }
                        start_group.setQuestions(questions);
                    }
                }else {
                    ExUserAnserQueryCriteria criteria = new ExUserAnserQueryCriteria();
                    criteria.setUserName(userName);
                    criteria.setPublishPaperId(publishPaperId);
                    criteria.setPublishGroupId(start_group.getPublishGroupId());
                    UserAnserDto userScore = exUserAnserService.getUserScore(criteria);
                    if (UtilValidate.isNotEmpty(userScore)) {
                        oneResultDto.setQuestionType("选择题");
                        if (UtilValidate.isNotEmpty(userScore.getQuestionNum())&&userScore.getQuestionNum()>0) {
                            oneResultDto.setSubmit(true);
                            oneResultDto.setResult1(userScore);
                        }
                        publishPaper.setUserScore(oneResultDto);
                    }
                }
                start_group.setStatus(2);
                start_group.setQuestions(null);
                publishPaper.setStartGroup(start_group);

            }
            //考试还在进行中
            if(index!=null){
                start_group=groups.get(index);
                List<ExPublishQuestion> questions = start_group.getQuestions();
                String type = questions.get(0).getType();
                String questionType="";
                if(UtilValidate.isNotEmpty(type)){
                    if(HengLiConstants.xing_ge_question.equals(type)){
                        questionType="性格测试题";
                    }else{
                        questionType="选择题";
                    }
                }
                GroupOneResultDto oneResultDto=new GroupOneResultDto();
                oneResultDto.setGroupName(start_group.getCategoryName());
                oneResultDto.setRuleType(exPaper.getRuleType());
                if("性格测试题".equals(questionType)){
                    oneResultDto.setQuestionType("性格测试题");
                    ExUserAnserQueryCriteria c13=new ExUserAnserQueryCriteria();
                    c13.setPublishPaperId(publishPaperId);
                    c13.setUserName(userName);
                    c13.setPublishGroupId(start_group.getPublishGroupId());
                    UserXingGeAnserDto xingGeAnserDto = exUserAnserService.xinGeCountLetterGroup(c13);
                    if(UtilValidate.isNotEmpty(xingGeAnserDto)){
                        oneResultDto.setSubmit(true);
                        oneResultDto.setResult2(xingGeAnserDto);
                    }
                    /**
                     * 判断是否需要打乱选项
                     */
                    if(exPaper.getIsDerange()==1){
                        //不打乱选项
                        //选打乱题目
                        Collections.shuffle(questions);

                        //重新排序
                        for (int i = 0; i < questions.size(); i++) {
                            ExPublishQuestion publishQuestion = questions.get(i);
                            publishQuestion.setSort(i+1);
                        }
                        start_group.setQuestions(questions);
                    }
                }else{
                    ExUserAnserQueryCriteria criteria=new ExUserAnserQueryCriteria();
                    criteria.setUserName(userName);
                    criteria.setPublishPaperId(publishPaperId);
                    criteria.setPublishGroupId(start_group.getPublishGroupId());
                    UserAnserDto userScore = exUserAnserService.getUserScore(criteria);
                    if(UtilValidate.isNotEmpty(userScore)){
                        oneResultDto.setQuestionType("选择题");
                        if(userScore.getQuestionNum()!=null&&userScore.getQuestionNum()>0){
                            oneResultDto.setSubmit(true);
                            oneResultDto.setResult1(userScore);
                        }
                        publishPaper.setUserScore(oneResultDto);
                    }

                    /**
                     * 判断是否需要打乱选项
                     */
                    if(exPaper.getIsDerange()==1&&UtilValidate.isNotEmpty(start_group.getIsDerangeOption())&&start_group.getIsDerangeOption()==1){
                        //先打乱选项再打乱题目顺序
                        for(ExPublishQuestion question :  questions){
                            //字母集合
                            List<String> arr=new ArrayList<>();
                            List<ExPublishOption> options = question.getOptions();
                            for(ExPublishOption option: options){
                                arr.add(option.getLetter());
                            }
                            if(exPaper.getIsDerange()==1){
                                //打乱选项
                                Collections.shuffle(options);
                            }

                            for(int i=0; i<options.size(); i++){
                                options.get(i).setLetter(arr.get(i));
                            }
                            question.setOptions(options);
                        }
                        //选打乱题目
                        Collections.shuffle(questions);

                        //重新排序
                        for (int i = 0; i < questions.size(); i++) {
                            ExPublishQuestion publishQuestion = questions.get(i);
                            publishQuestion.setSort(i+1);
                        }
                        start_group.setQuestions(questions);
                    }
                }
                /**
                 * 计算给前台的倒计时显示 因服务器会存在 时差 需要按服务器时间为准
                 */
                if(UtilValidate.isNotEmpty(start_group.getEndTime())){
                    long d=start_group.getEndTime().getTime()- System.currentTimeMillis();
                    if(d>0){
                        BigDecimal limit=  new BigDecimal(d).divide(new BigDecimal(1000)).setScale(0,BigDecimal.ROUND_HALF_UP);
                        start_group.setResidueTime(limit.intValue()+2);
                    }
                }

                publishPaper.setStartGroup(start_group);
                ExPublishGroup nextGroup=null;//下一组
                if(index<groups.size()-1){
                    nextGroup= groups.get(index+1);
                }
                publishPaper.setNextGroup(nextGroup);
            }
        }
        GroupOneResultDto userScore = publishPaper.getUserScore();
        //设置考试结束标志
        if(userScore!=null&&!userScore.isPaperOver()){
            if(publishPaper.getStatus()==2){
                userScore.setPaperOver(true);
            }
        }

        return publishPaper;
    }

    /**
     * 切换到下一模块
     * @param exPublishPaper
     */
    @Override
    public void startPublishPaper(ExPublishPaper exPublishPaper) {
        ExPublishPaper publishPaper = getPublishPaper(exPublishPaper);
        ExPaper exPaper = publishPaper.getExPaper();
        Integer model = exPaper.getModel();// 考试模式: 1单一模块 2整张试卷
        Integer limitTime = exPaper.getLimitTime();//考试分钟数
        Integer groupIndex=0;//正在进行考试模块下标
        List<ExPublishGroup> groups = publishPaper.getGroups();
        ExPublishGroup start_group=null;//要开始 的组
        //开始考试
        if(publishPaper.getStatus()==0){
            publishPaper.setStatus(1);
            //收集哪些状态不是0的组
            List<ExPublishGroup> gs_n0=new ArrayList<>();
            for(ExPublishGroup group: groups){
                if(group.getStatus()!=0){
                    group.setStatus(0);
                    gs_n0.add(group);
                }
            }
            groupIndex=0;
            start_group = groups.get(0);
            start_group.setStatus(1);
            Date date = new Date();
            start_group.setStartTime(new Timestamp(date.getTime()));
            publishPaper.setStartTime(start_group.getStartTime());
            Date end_date = DateKit.dateAdd(6, date, start_group.getLimitTime());
            start_group.setEndTime(new Timestamp(end_date.getTime()));
            gs_n0.add(start_group);

            //加入到redis标识
            if(exPaper.getIsCoerce()==1){
                redisUtil.setIfAbsent(RedisKeyManager.team_paper_key+publishPaper.getPublishPaperId(),publishPaper.getPublishPaperId(),12,TimeUnit.HOURS);
            }
            exPublishGroupService.saveOrUpdateBatch(gs_n0);

        }else if(publishPaper.getStatus()==1){
            groupIndex = publishPaper.getGroupIndex();
            if(groupIndex!=null){
                start_group = groups.get(groupIndex);
            }
            //切换到下一组
            if(model==1){

                if(UtilValidate.isNotEmpty(start_group)
                &&start_group.getStatus()==1){
//                    throw new YmException("当前模块考试未完成！");
                    ExPublishGroup u_start_group=new ExPublishGroup();
                    u_start_group.setPublishGroupId(start_group.getPublishGroupId());
                    u_start_group.setStatus(2);
                    u_start_group.setEndTime(new Timestamp(System.currentTimeMillis()));
                    exPublishGroupService.updateById(u_start_group);
                }
                if(groupIndex<groups.size()-1){
                    groupIndex++;
                    start_group = groups.get(groupIndex);
                    start_group.setStatus(1);
                    Date date = new Date();
                    start_group.setStartTime(new Timestamp(date.getTime()));
                    Date end_date = DateKit.dateAdd(6, date, limitTime);
                    start_group.setEndTime(new Timestamp(end_date.getTime()));
                    exPublishGroupService.saveOrUpdate(start_group);
                }else{
                    throw new YmException("--这是最后一个了，定时器自己会关闭 整个考试!");


                }
            }else{
                throw new YmException("整张试卷 已经开考了 不要重复点击开考!");
            }

        }
        publishPaper.setGroupIndex(groupIndex);
        ExPublishGroup nextGroup=null;//下一组
        if(groupIndex<groups.size()-1){
            nextGroup= groups.get(groupIndex+1);
        }
//        else if(groupIndex==groups.size()-1){
//            nextGroup= groups.get(groupIndex);
//        }
        publishPaper.setNextGroup(nextGroup);
        saveOrUpdate(publishPaper);
        if(UtilValidate.isNotEmpty(start_group)){
            publishPaper.setStartGroup(start_group);
            //广播开始考试
            UserExWebSocket.broadcastStartPaper(publishPaper);
            LocalDateTime startTime = start_group.getStartTime().toLocalDateTime();
            LocalDateTime endTime = start_group.getEndTime().toLocalDateTime();
            //结束交卷定时器
            if(exPaper.getIsCoerce()==1){
                System.out.println("----已开启强制交卷");
              //  exTaskScheduler.startTimerWithShutdownTime(startTime,endTime,publishPaper);
            }
        }

    }


    @Override
    public void shoudongTongzhi(String publishPaperId) {
        ExPublishPaper n_p=new ExPublishPaper();
        n_p.setPublishPaperId(publishPaperId);
        ExPublishPaper userPaper = getPublishPaper(n_p);
        //修改数据状态
//        upNextGroup(userPaper);
        Timestamp endTime = null;
        if(UtilValidate.isNotEmpty(userPaper.getGroupIndex())){
            List<ExPublishGroup> groups = userPaper.getGroups();

            ExPublishGroup startGroup = groups.get(userPaper.getGroupIndex());
            endTime=startGroup.getEndTime();
        }

        Integer limitTime=null;
        //通知考试结束获取排行榜信息
        if (userPaper.getStatus() == 2) {
            //    limitTime=30;
        }
        log.info("---手动 交卷时 考试状态:"+userPaper.getStatus()+";publishPaperId:"+userPaper.getPublishPaperId());

        //格式化结束时间
        // 定义日期时间格式
        String endDateTime ="";
        if(UtilValidate.isNotEmpty(endTime)){
            Date endDate = new Date(endTime.getTime());
            endDateTime=DateKit.dateFormat(endDate);
        }


        try{
            UserExWebSocket.broadcastSysSubmitPaper(userPaper,limitTime,endDateTime);
        }catch (Exception e){
            log.error("----发送手动 交卷广播异常"+e.getMessage(),e);
        }
    }

    @Override
    public UserAnserDto sysSubmitPaper(ExPublishPaper exPublishPaper,String userName) {
        List<ExPublishGroup> groups = exPublishPaper.getGroups();
        Integer groupIndex = exPublishPaper.getGroupIndex();
        ExPublishGroup startGroup = exPublishPaper.getStartGroup();
        List<ExPublishQuestion> questions = startGroup.getQuestions();
        ExUserAnserQueryCriteria criteria=new ExUserAnserQueryCriteria();
        criteria.setUserName(userName);
        criteria.setPublishPaperId(exPublishPaper.getPublishPaperId());
        criteria.setPublishGroupId(startGroup.getPublishGroupId());
//        List<ExUserAnser> exUserAnsers = exUserAnserService.queryAll(criteria);
//        if(UtilValidate.isNotEmpty(exUserAnsers)){
//           // throw new YmException("你已经提交过该模块的题目!");
//        }

        ExTeamUser teamUser = exTeamUserService.findByUserName(userName);
        if(UtilValidate.isEmpty(teamUser)){
            teamUser = new ExTeamUser();
            teamUser.setUserName(userName);
            teamUser.setUserId("场外人员:"+userName);
            exTeamUserService.save(teamUser);
        }
        ExUserPaper exUserPaper= userJoinPaper(userName, exPublishPaper.getPublishPaperId());
       // exUserOptionService

        for (ExPublishQuestion question : questions) {
            List<ExPublishOption> options = question.getOptions();
            ExUserAnser userAnswer=new ExUserAnser();
            userAnswer.setPublishPaperId(exPublishPaper.getPublishPaperId());
            userAnswer.setUserName(userName);
            if(UtilValidate.isNotEmpty(teamUser)){
                userAnswer.setUserId(teamUser.getUserId());
            }
            userAnswer.setPublishQuestionId(question.getPublishQuestionId());
            userAnswer.setPublishGroupId(question.getPublishGroupId());
            if(UtilValidate.isNotEmpty(exUserPaper)){
                userAnswer.setUserPaperId(exUserPaper.getUserPaperId());
            }

            int have_anser=0;
            int user_true_num=0;//你选了正确的选项数量
            int user_erro_num=0;//你选了错误的选项数量
            int question_true_num=0;//总共正确的选项数量
            boolean allTrue=false;
            //收集用户选项
            List<ExUserOption> userOptions=new ArrayList<>();
            for (ExPublishOption option : options) {
                if(option.getIsTrue()==1){
                    question_true_num++;
                }
                if(UtilValidate.isNotEmpty(option.getCheck())&&option.getCheck()){
                    have_anser=1;
                    ExUserOption userOption = new ExUserOption();
                    userOption.setPublishPaperId(exPublishPaper.getPublishPaperId());
                    userOption.setPublishGroupId(question.getPublishGroupId());
                    userOption.setIsTrue(option.getIsTrue());
                    if(option.getIsTrue()==1){
                        user_true_num++;
                    }else{
                        user_erro_num++;
                    }
                    userOption.setPublishQuestionId(question.getPublishQuestionId());
                    userOption.setSort(option.getSort());
                    userOption.setPublishOptionId(option.getId());
                    userOption.setUserName(userName);
                    if(UtilValidate.isNotEmpty(teamUser)){
                        userOption.setUserId(teamUser.getUserId());
                    }
                    userOptions.add(userOption);
                }else{
                }

            }
            //判断这道题对不对
            if(question_true_num==user_true_num&&user_erro_num==0){
                allTrue=true;
            }

            ExTeam team =null;
            if(UtilValidate.isNotEmpty(teamUser.getTeamId())){
                 team = exTeamService.getById(teamUser.getTeamId());

            }else{
                //无归属队伍2
                 team = exTeamService.geyByName("15组");
                teamUser.setTeamId(team.getTeamId());
                exTeamUserService.saveOrUpdate(teamUser);
            }
            //答对逻辑
            ExTeam team2 =null;
            ExQuestion question_info = exQuestionService.getById(question.getQuestionId());
            boolean iz_test=false;//理论测试
            //查找部门
            if(UtilValidate.isEmpty(question_info.getTeamId())){
                ExCategory topParent = exCategoryServiceImpl.findTopParent(question_info.getCategoryId());
                if(UtilValidate.isNotEmpty(topParent)){
                    question_info.setTeamId(topParent.getTeamId());
                    if(topParent.getCategoryName().contains("理论测试")){
                        iz_test=true;
                    }
                }

            }
            if(UtilValidate.isNotEmpty(question_info)&&UtilValidate.isNotEmpty(question_info.getTeamId())){

                team2 = exTeamService.teamDetail(question_info.getTeamId());
            }
            ExTeamRule teamRule=null;
            if(UtilValidate.isEmpty(team2)){
                System.out.println("---没有设置团队:"+question.getQuestionId());
            }
            //匹配规则
            if(!iz_test){
                List<ExTeamRule> rules = team2.getRules();
                if(UtilValidate.isNotEmpty(rules)){
                    //是不是本部门
                    boolean isDept=false;
                    if(team.getDeptName().equals(team2.getDeptName())){
                        isDept=true;
                    }
                    log.info("-----isDept:"+isDept+";"+userName+":"+question.getQuestionId());
                    for(ExTeamRule rule:rules){
                        if(isDept&&rule.getType().equals("本部门")){
                            teamRule =rule;
                        }
                        if(!isDept&&rule.getType().equals("非本部门")){
                            teamRule =rule;
                        }
                    }
                }
            }else{
                teamRule=team2.getRules().get(0);
            }

            if(UtilValidate.isEmpty(teamRule)){
                System.out.println("--没有匹配到规则!");
            }
            if(UtilValidate.isNotEmpty(teamRule)){
                if(allTrue){
                    userAnswer.setIsTrue(1);
                    if(UtilValidate.isNotEmpty(teamRule.getTrueScore())){
                        userAnswer.setScore(teamRule.getTrueScore());
                    }else{
                        userAnswer.setScore(0);
                    }
                }
                else{
                    //答错逻辑
                    if(UtilValidate.isNotEmpty(teamRule.getErroScore())){
                        userAnswer.setScore(teamRule.getErroScore());
                    }else{
                        userAnswer.setScore(0);
                    }
                    userAnswer.setIsTrue(0);
                }
                userAnswer.setTeamRuleId(teamRule.getId());
                //如果是测试模块不计分
                if(UtilValidate.isNotEmpty(startGroup.getAzTest())&&startGroup.getAzTest()==1){
                    userAnswer.setScore(0);
                    userAnswer.setIzDist(1);
                }
            }

            userAnswer.setHaveAnser(have_anser);
            exUserAnserService.saveOrUpdate(userAnswer);
            exUserOptionService.saveOrUpdateBatch(userOptions);
        }

        boolean con=groupIndex==groups.size()-1;
        log.info("---是否为最后一个模块:"+con+";"+userName);
        if(groupIndex==groups.size()-1){
            //交卷 算出得分
            //非最后一个模块的分数返回
            ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
            c1.setPublishPaperId(exPublishPaper.getPublishPaperId());
            c1.setUserName(userName);
            UserAnserDto userScore = exUserAnserService.getUserScore(c1);
            //用户增加分数
//            Integer score = UtilValidate.isNotEmpty(teamUser.getScore())?teamUser.getScore():0;
//            score=score+userScore.getResultScore();
//            teamUser.setScore(score);
//            exTeamUserService.saveOrUpdate(teamUser);

            log.info("---保存分数:"+userScore.getResultScore()+";"+userName+";user_paper_id:"+exUserPaper.getUserPaperId());
            exUserPaper.setScore(userScore.getResultScore());
            exUserPaper.setEndTime(new Timestamp(System.currentTimeMillis()));
            exUserPaperService.saveOrUpdate(exUserPaper);
           // exPublishPaper.setUserScore(userScore);
            userScore.setPaperOver(true);
            return userScore;
//            //发送给客户端
          //  UserExWebSocket.sendToUserScore(exPublishPaper);
        }
        //非最后一个模块的分数返回
        ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
        c1.setPublishPaperId(exPublishPaper.getPublishPaperId());
        c1.setUserName(userName);
        c1.setPublishGroupId(startGroup.getPublishGroupId());
        UserAnserDto userScore = exUserAnserService.getUserScore(c1);
        userScore.setPaperOver(false);
        return userScore;
    }


    /**
     * 面试人员提交试卷
     * @param exPublishPaper
     * @param userName
     * @return
     */
    @Override
    public GroupOneResultDto userSubmitPaper(ExPublishPaper exPublishPaper, String userName) {

        GroupOneResultDto oneResultDto=new GroupOneResultDto();
        oneResultDto.setSubmit(true);
        List<ExPublishGroup> groups = exPublishPaper.getGroups();
        String userId = getUserId();
//        ExPaper paper = exPaperService.getByPublishPaperId(exPublishPaper.getPublishPaperId());
        ExUserGroupQueryCriteria c=new ExUserGroupQueryCriteria();
        c.setPublishPaperId(exPublishPaper.getPublishPaperId());
        c.setUserName(userName);
        List<ExUserGroup> exUserGroups = exUserGroupService.queryAll(c);
        ExPublishGroup startGroup = exPublishPaper.getStartGroup();


//        for (int i = 0; i < exUserGroups.size(); i++) {
//            ExUserGroup exUserGroup = exUserGroups.get(i);
//            if(exUserGroup.getPublishGroupId().equals(startGroup.getPublishGroupId())){
//                index=i;
//
//            }
//        }
        //判断是否有到达时间点 会和定时器的逻辑冲突
        UserGroupIngDto userGroupIngDto = exUserGroupService.izArriveEndTime(exUserGroups);
        Integer  index =userGroupIngDto.getIng_index();
        exUserGroupService.izGoTimeUserGroup(exUserGroups,true);
        System.out.println(index);
//        ExPublishGroup group = groups.get(index);

        List<ExPublishQuestion> questions = startGroup.getQuestions();

        ExUserPaper exUserPaper= userJoinPaper(userName, exPublishPaper.getPublishPaperId());

        for (ExPublishQuestion question : questions) {
            List<ExPublishOption> options = question.getOptions();
            ExUserAnser userAnswer=new ExUserAnser();
            userAnswer.setPublishPaperId(exPublishPaper.getPublishPaperId());
            userAnswer.setUserName(userName);
            userAnswer.setUserId(userId);
            userAnswer.setPublishQuestionId(question.getPublishQuestionId());
            userAnswer.setPublishGroupId(question.getPublishGroupId());
            if("性格与沟通".equals(question.getType())){
                userAnswer.setIzDist(1);//不区分对错
                oneResultDto.setQuestionType("性格测试题");
            }else{
                oneResultDto.setQuestionType("选择题");
            }

            if(UtilValidate.isNotEmpty(exUserPaper)){
                userAnswer.setUserPaperId(exUserPaper.getUserPaperId());
            }

            //区分对错
            int have_anser=0;
            int user_true_num=0;//你选了正确的选项数量
            int user_erro_num=0;//你选了错误的选项数量
            int question_true_num=0;//总共正确的选项数量
            boolean allTrue=false;
            //收集用户选项
            List<ExUserOption> userOptions=new ArrayList<>();
            for (ExPublishOption option : options) {
                if(option.getIsTrue()==1){
                    question_true_num++;
                }
                if(UtilValidate.isNotEmpty(option.getCheck())&&option.getCheck()){
                    have_anser=1;
                    ExUserOption userOption = new ExUserOption();
                    userOption.setPublishPaperId(exPublishPaper.getPublishPaperId());
                    userOption.setPublishGroupId(startGroup.getPublishGroupId());
                    userOption.setIsTrue(option.getIsTrue());
                    if(option.getIsTrue()==1){
                        user_true_num++;
                    }else{
                        user_erro_num++;
                    }
                    userOption.setPublishQuestionId(question.getPublishQuestionId());
                    userOption.setSort(option.getSort());
                    userOption.setPublishOptionId(option.getId());
                    userOption.setUserName(userName);
                    userOption.setUserId(userId);

                    userOptions.add(userOption);
                }else{
                }

            }
            if(UtilValidate.isEmpty(userAnswer.getIzDist())){
                //需要区分对错
                //判断这道题对不对
                if(question_true_num==user_true_num&&user_erro_num==0){
                    allTrue=true;
                }
                if(allTrue){
                    userAnswer.setIsTrue(1);
                }
                else{
                    userAnswer.setIsTrue(0);
                }
                //如果是测试模块不计分
                if(UtilValidate.isNotEmpty(startGroup.getAzTest())&&startGroup.getAzTest()==1){
                    userAnswer.setScore(0);
                    userAnswer.setIzDist(1);
                }else if(UtilValidate.isNotEmpty(startGroup.getTrueType0())&&userAnswer.getIsTrue()==1){
                    userAnswer.setScore(startGroup.getTrueType0());
                }
            }else{
                //无需区分对错的话 分数设置成0
                userAnswer.setScore(0);
            }
            userAnswer.setHaveAnser(have_anser);
            exUserAnserService.saveOrUpdate(userAnswer);

            exUserOptionService.saveOrUpdateBatch(userOptions);
        }
        if(UtilValidate.isEmpty(index)){
            /**
             * 没有正在进行的模块则显示分数
             */
            oneResultDto.setPaperOver(true);
            ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
            c1.setPublishPaperId(exPublishPaper.getPublishPaperId());
            c1.setUserName(userName);
            UserAnserDto userScore = exUserAnserService.getUserScore(c1);
            oneResultDto.setResult1(userScore);
            return oneResultDto;
        }
        boolean con=index==groups.size()-1;
        log.info("---index:"+index);
        log.info("---是否为最后一个模块:"+con+";"+userName);

        if(con){
            oneResultDto.setPaperOver(true);
            //交卷 算出得分
            //非最后一个模块的分数返回
            ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
            c1.setPublishPaperId(exPublishPaper.getPublishPaperId());
            c1.setUserName(userName);
            UserAnserDto userScore = exUserAnserService.getUserScore(c1);

            log.info("---保存分数:"+userScore.getResultScore()+";"+userName+";user_paper_id:"+exUserPaper.getUserPaperId());

            exUserPaper.setScore(userScore.getResultScore());
            exUserPaper.setEndTime(new Timestamp(System.currentTimeMillis()));//记录交卷试卷
            exUserPaperService.saveOrUpdate(exUserPaper);

            //清除 redis标志
            redisUtil.remove(RedisKeyManager.user_token_key+exUserPaper.getUserPaperId());

            // exPublishPaper.setUserScore(userScore);
//            userScore.setPaperOver(true);
//            return oneResultDto;
//            //发送给客户端
            //  UserExWebSocket.sendToUserScore(exPublishPaper);
        }
        //非最后一个模块的分数返回
        if("性格测试题".equals(oneResultDto.getQuestionType())){
            ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
            c1.setPublishPaperId(exPublishPaper.getPublishPaperId());
            c1.setUserName(userName);
            c1.setPublishGroupId(startGroup.getPublishGroupId());
            UserXingGeAnserDto xingGeAnserDto=exUserAnserService.xinGeCountLetterGroup(c1);

            oneResultDto.setResult2(xingGeAnserDto);
        }else{
            //选择题
            ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
            c1.setPublishPaperId(exPublishPaper.getPublishPaperId());
            c1.setUserName(userName);
            c1.setPublishGroupId(startGroup.getPublishGroupId());
            UserAnserDto userScore = exUserAnserService.getUserScore(c1);

            oneResultDto.setResult1(userScore);
        }

        return oneResultDto;

    }

    @Override
    public void upNextGroup(ExPublishPaper exPublishPaper) {

        ExPublishGroup startGroup = exPublishPaper.getStartGroup();
        if(UtilValidate.isNotEmpty(startGroup)){
            startGroup.setStatus(2);
            exPublishGroupService.saveOrUpdate(startGroup);
        }
        ExPublishGroup nextGroup = exPublishPaper.getNextGroup();
//        ExPaper exPaper = exPublishPaper.getExPaper();
        if(UtilValidate.isEmpty(nextGroup)){
            exPublishPaper.setStatus(2);
            exPublishPaper.setEndTime(new Timestamp(System.currentTimeMillis()));
            exPublishPaper.setShowRank(1);
            saveOrUpdate(exPublishPaper);
        }


    }

    public void autoStartGroup(ExPublishGroup nextGroup,Integer limitTime){
        nextGroup.setStatus(1);
        Date now = new Date();
        nextGroup.setStartTime(new Timestamp(now.getTime()));
        Date end_date = DateKit.dateAdd(6, now, limitTime);
        nextGroup.setEndTime(new Timestamp(end_date.getTime()));
        exPublishGroupService.saveOrUpdate(nextGroup);
    }

    @Override
    public void recoverPublishPaper(String publishPaperId) {
        ExPublishPaper exPublishPaper=new ExPublishPaper();
        exPublishPaper.setPublishPaperId(publishPaperId);

        ExPublishPaper publishPaper = getPublishPaper(exPublishPaper);
        ExPaper exPaper = publishPaper.getExPaper();
//        Integer limitTime = publishPaper.getExPaper().getLimitTime();
        List<ExPublishGroup> groups = publishPaper.getGroups();
        groups.forEach(group -> {
            group.setStatus(0);
            group.setIzAgain(0);
            group.setStartTime(null);
            group.setEndTime(null);
        });
        if(exPaper.getRuleType()==0){
            //面试卷
            exPublishPaper.setStatus(1);
        }else{
            exPublishPaper.setStatus(0);
        }
        saveOrUpdate(exPublishPaper);
        groups.forEach(group -> {
//            System.out.println("--修改模块");
            exPublishGroupService.saveOrUpdate(group);
        });


        //删除用户答题记录
        LambdaQueryWrapper<ExUserAnser> userAnserLambdaQueryWrapper=new LambdaQueryWrapper<>();
        userAnserLambdaQueryWrapper.eq(ExUserAnser::getPublishPaperId,publishPaperId);
        exUserAnserService.remove(userAnserLambdaQueryWrapper);
        LambdaQueryWrapper<ExUserOption> userOptionLambdaQueryWrapper=new LambdaQueryWrapper<>();
        userOptionLambdaQueryWrapper.eq(ExUserOption::getPublishPaperId,publishPaperId);
        exUserOptionService.remove(userOptionLambdaQueryWrapper);
        //删除试卷
        LambdaQueryWrapper<ExUserPaper> exUserPaperLambdaQueryWrapper=new LambdaQueryWrapper<>();
        exUserPaperLambdaQueryWrapper.eq(ExUserPaper::getPublishPaperId,publishPaperId);
        exUserPaperService.remove(exUserPaperLambdaQueryWrapper);
        //删除 user_group
        LambdaQueryWrapper<ExUserGroup> exUserGroupLambdaQueryWrapper=new LambdaQueryWrapper<>();
        exUserGroupLambdaQueryWrapper.eq(ExUserGroup::getPublishPaperId,publishPaperId);
        exUserGroupService.remove(exUserGroupLambdaQueryWrapper);
    }


    @Override
    public UserAnserDetailDto getUserScore(String publishPaperId, String userName) {
        //交卷 算出得分
        ExUserAnserQueryCriteria c1=new ExUserAnserQueryCriteria();
        c1.setPublishPaperId(publishPaperId);
        c1.setUserName(userName);
        UserAnserDetailDto userScore = exUserAnserService.getUserScoreDetail(c1);
        return userScore;
    }


    @Override
    public void exScheduledSeconds() {
        autoCloseTeamGroup();
        exUserPaperService.autoCloseUserGroup();
    }

    /**
     * 团队考试自动进行到下一个考试
     */
    @Override
    public void autoCloseTeamGroup() {
        Set<String> keys = redisUtil.keys(RedisKeyManager.team_paper_key + "*");
        for (String key : keys) {
            String publishPaperId = redisUtil.getString(key);
            ExPublishPaper publishPaper = getById(publishPaperId);
            if(UtilValidate.isNotEmpty(publishPaper)){
                ExPaper exPaper = exPaperService.getById(publishPaper.getPaperId());
                publishPaper.setExPaper(exPaper);
                ExPublishGroupQueryCriteria c1=new ExPublishGroupQueryCriteria();
                c1.setPublishPaperId(publishPaper.getPublishPaperId());
                List<ExPublishGroup> groups = exPublishGroupService.queryAll(c1);
                Integer groupIndex = null;
                ExPublishGroup start_group =null;
                Integer model = exPaper.getModel();
                if(publishPaper.getStatus()==1){
                    groupIndex = publishPaper.getGroupIndex();
                    if(groupIndex!=null){
                        start_group = groups.get(groupIndex);
                    }else{
                        publishPaper.setStatus(2);
                        saveOrUpdate(publishPaper);
                    }
                    // model 考试模式: 1单一模块 2整张试卷
                    //切换到下一组
//                    if(model==1){
//
//                    }

                    if(UtilValidate.isNotEmpty(start_group)
                            &&start_group.getStatus()==1){
//                    throw new YmException("当前模块考试未完成！");

                        Date now = new Date();
                        Date endDate=new Date(start_group.getEndTime().getTime());
                        int result = now.compareTo(endDate);
                        log.info("---判断 团队试卷 有没有 到达时间点了:"+ DateKit.dateFormat(now));
                        //到达时间点了
                        if(result>=0){
                            log.info("---团队试卷 到达时间点了：;publishGroupId:"+start_group.getPublishGroupId());
                            ExPublishGroup u_start_group=new ExPublishGroup();
                            u_start_group.setPublishGroupId(start_group.getPublishGroupId());
                            u_start_group.setStatus(2);
//                            u_start_group.setEndTime(new Timestamp(System.currentTimeMillis()));
                            exPublishGroupService.updateById(u_start_group);

                            if(groupIndex<groups.size()-1){
//                                groupIndex++;
//                                start_group = groups.get(groupIndex);
//                                start_group.setStatus(1);
//                                Date date = new Date();
//                                start_group.setStartTime(new Timestamp(date.getTime()));
//                                Date end_date = DateKit.dateAdd(6, date, start_group.getLimitTime());
//                                start_group.setEndTime(new Timestamp(end_date.getTime()));
//                                exPublishGroupService.saveOrUpdate(start_group);
                            }else{
                                publishPaper.setStatus(2);
                            }

                            publishPaper.setGroupIndex(groupIndex);
                            ExPublishGroup nextGroup=null;//下一组
                            if(groupIndex<groups.size()-1){
                                nextGroup= groups.get(groupIndex+1);
                            }

                            publishPaper.setNextGroup(nextGroup);
                            saveOrUpdate(publishPaper);
                            if(UtilValidate.isNotEmpty(start_group)){
                                publishPaper.setStartGroup(start_group);
                                //广播开始考试
                              //  UserExWebSocket.broadcastStartPaper(publishPaper);
                                //通知交卷
                                shoudongTongzhi(publishPaper.getPublishPaperId());

                            }


                        }

                    }


                }else {
                    //移除key
                    redisUtil.remove(RedisKeyManager.team_paper_key + publishPaperId);
                }

            }

        }
    }

    @Override
    public void autoStartPaper() {

        Set<String> keys = redisUtil.keys("startPublishPaper:*");
        System.out.println("---keys:"+keys);
        for (String key : keys) {
            String publishPaperId = redisUtil.get(key)+"";
            ExPublishPaperQueryCriteria c1=new ExPublishPaperQueryCriteria();
            c1.setActive(1);
            c1.setStatus(0);
            c1.setPublishPaperId(publishPaperId);
            List<ExPublishPaper> exPublishPapers = queryAll(c1);
            if(UtilValidate.isNotEmpty(exPublishPapers)){
                //开启考试
                startPublishPaper(exPublishPapers.get(0));
                redisUtil.remove("startPublishPaper:" + publishPaperId);
            }
        }


    }
}
